#ifndef WORKER
#define WORKER

/*!
 * \file Worker.h
 * \author aimery aviles / thomas raynal
 * \version 2.0
 */


#include <vector>
#include <string>
#include <iostream>
#include "AbstractTask.h"

#define UNDEFINED -1

/*! \namespace Network
 * 
 * Group master/slave task template & task handling utilities (trees & graphs)
 */
namespace MasterWorkerFramework
{
/*! \class Worker
* \brief Represent a node in a slave task graph
*/
class Worker
{
public:

	Worker (AbstractGridSlaveTask* task)
	{
		id_ = task->GetHash();
		index_= UNDEFINED;
		name_ = task->GetName();
		link_=0;
		task_= task;
		edges_ = new std::vector<Worker*>();
	}

	/*!
	*  \brief Get the worker name
	*
	*/
	std::string* GetName()
	{
		return name_;
	}

	/*!
	*  \brief Get the binded task
	*
	*/
	AbstractGridSlaveTask* GetTask()
	{
		return task_;
	}
	
	/*!
	*  \brief Get the worker id
	*
	*/
	std::string* GetId()
	{
		return id_;
	}

	/*!
	*  \brief Get the worker dependancy index
	*
	*/
	int GetIndex()
	{
		return index_;
	}

	/*!
	*  \brief Add an edge to the worker
	*
	*/
	void AddEdge(Worker* n)
	{
		if (!(std::find(edges_->begin(), edges_->end(), n) != edges_->end()))
		{
			edges_->push_back(n);
		}
	}

	/*!
	*  \brief Is the worker ready for processing?
	*
	*/
	bool IsReady ()
	{
		bool ready = true;
		for (std::vector<Worker*>::iterator worker = edges_->begin(); worker != edges_->end(); worker++)
		{
			if ((*worker)->GetTask()->GetStatut()==TASK_STATUT::PENDING || (*worker)->GetTask()->GetStatut()==TASK_STATUT::SENT)
			{
				ready = false;
				break;
			}
		}

		return ready;
	}

	/*!
	*  \brief Resolve worker dependancies
	*
	*/
	void Resolve()
	{
		for (std::vector<Worker*>::iterator worker = edges_->begin(); worker != edges_->end(); worker++)
		{
			(*worker)->Resolve();
		}
	}

	inline bool operator==(Worker& worker)
	{
		if (worker.GetId()==GetId())
			return true;
		return false;
	}

private:
	std::string* id_;
	std::string* name_;
	int index_;
	int link_;
	std::vector<Worker*>* edges_;
	AbstractGridSlaveTask* task_;

	friend class WorkerTree;
	
};
}
#endif